package org.qq120011676.fileserver.fileserver.helper.impl;

import io.minio.*;
import io.minio.errors.ErrorResponseException;
import lombok.SneakyThrows;
import org.qq120011676.fileserver.fileserver.config.FileserverConfig;
import org.qq120011676.fileserver.fileserver.helper.BaseStorageHelper;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.util.Objects;

@Primary
@ConditionalOnExpression("!'${fileserver.minio.endpoint:}'.isEmpty()")
@Component
public class MinioStorageHelper extends BaseStorageHelper {
    private final MinioClient minioClient;
    private final FileserverConfig.Minio minioConfig;

    @SneakyThrows
    public MinioStorageHelper(FileserverConfig fileserverConfig) {
        super(fileserverConfig);
        minioConfig = super.getFileserverConfig().getMinio();
        minioClient = MinioClient.builder()
                .endpoint(minioConfig.getEndpoint())
                .credentials(minioConfig.getAccessKey(),
                        minioConfig.getSecretKey())
                .build();
        // 检查存储桶是否存在，不存在则创建
        if (!minioClient.bucketExists(BucketExistsArgs.builder()
                .bucket(minioConfig.getBucketName())
                .build())) {
            minioClient.makeBucket(MakeBucketArgs.builder()
                    .bucket(minioConfig.getBucketName())
                    .build());
        }
    }

    @SneakyThrows
    @Override
    public void save(String objectName, byte[] bytes) {
        // 上传文件
        try (ByteArrayInputStream in = new ByteArrayInputStream(bytes)) {
            minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket(minioConfig.getBucketName())
                            .object(objectName)
                            .stream(in, bytes.length, -1)
                            .build());
        }
    }

    /**
     * 下载文件
     */
    @SneakyThrows
    @Override
    public byte[] get(String objectName) {
        try (GetObjectResponse getObjectResponse = minioClient.getObject(
                GetObjectArgs.builder()
                        .bucket(minioConfig.getBucketName())
                        .object(objectName)
                        .build())) {
            if (Objects.isNull(getObjectResponse)) {
                throw new RuntimeException("文件不存在");
            }
            return getObjectResponse.readAllBytes();
        }
    }

    @SneakyThrows
    @Override
    public boolean exist(String objectName) {
        try {
            minioClient.statObject(
                    StatObjectArgs.builder()
                            .bucket(minioConfig.getBucketName())
                            .object(objectName)
                            .build());
            return true;
        } catch (ErrorResponseException e) {
            if (Objects.equals(e.getMessage(), "Object does not exist")) {
                return false;
            }
            throw e;
        }
    }

    /**
     * 删除文件
     */
    @SneakyThrows
    @Override
    public void delete(String objectName) {
        minioClient.removeObject(
                RemoveObjectArgs.builder()
                        .bucket(minioConfig.getBucketName())
                        .object(objectName)
                        .build());
    }
}
